#include "hailstone.hh"
#include <iostream>
#include <fstream>
#include <vector>

// #define DEBUG

auto readHailstones() -> std::vector<Hailstone>
{
    std::vector<Hailstone> hailstones{};

    std::ifstream infile {"./src/day24/input.txt"};
    std::string line {};
    while (std::getline(infile, line))
        hailstones.emplace_back(line);

    return hailstones;
}

bool isCross(const Hailstone& hailstone1, const Hailstone& hailstone2)
{
    constexpr double minPosition {200000000000000};
    constexpr double maxPosition {400000000000000};

    double k1 {hailstone1.speedY / hailstone1.speedX};
    double k2 {hailstone2.speedY / hailstone2.speedX};
    double x1 {hailstone1.positionX};
    double y1 {hailstone1.positionY};
    double x2 {hailstone2.positionX};
    double y2 {hailstone2.positionY};

    if (k1 == k2 || k1 == -k1)
    {
#ifdef DEBUG
        std::cout << "Hailstones' paths are parallel; they never intersect." << std::endl;
#endif
        return false;     
    }

    double x {(k1 * x1 - k2 * x2 + y2 - y1) / (k1 - k2)};
    double y {k1 * x - k1 * x1 + y1};

    bool inHailstone1 {hailstone1.isInLine(x, y)};
    bool inHailstone2 {hailstone2.isInLine(x, y)};

#ifdef DEBUG
    if (inHailstone1 && inHailstone2)
        std::cout << "Hailstones' paths will cross inside the test area (at x=" << x << ", y=" << y << ")." << std::endl;
    else if ((!inHailstone1) && (!inHailstone2))
        std::cout << "Hailstones' paths crossed in the past for both hailstones." << std::endl;
    else if ((!inHailstone1) && inHailstone2)
        std::cout << "Hailstones' paths crossed in the past for hailstone A." << std::endl;
    else
        std::cout << "Hailstones' paths crossed in the past for hailstone B." << std::endl;
#endif

    if (inHailstone1 && inHailstone2)
    {
        if (minPosition > x || minPosition > y || maxPosition < x || maxPosition < y)
        {
#ifdef DEBUG
            std::cout << "Hailstones' paths will cross outside the test area (at x=" << x << ", y=" << y << ")." << std::endl;
#endif
            return false;
        }
        else
            return true;
    }
    else
        return false;
}

void part1(const std::vector<Hailstone>& hailstones)
{
    std::size_t count {0};
    for (std::size_t i = 0; i < hailstones.size(); ++i)
        for (std::size_t j = i + 1; j < hailstones.size(); ++j)
        {
            if (isCross(hailstones[i], hailstones[j]))
                count += 1;
        }
    std::cout << count << std::endl;
}

void part2(const std::vector<Hailstone>& hailstones)
{
    
}

int main()
{
    std::vector<Hailstone> hailstones {readHailstones()};
    part1(hailstones);   
}